#include "CMDispatcher.h"
#include "DataStorageCM.h"
#include "log.h"

CMDispatcher::CMDispatcher(AnalogSample& as,DataStorage& ds,PinName pin_int):
    _as(as),
    _ds(ds),
    _interrupt_pin(pin_int)
{

}
CMDispatcher::~CMDispatcher()
{

}

void CMDispatcher::begin()
{
    this->clear_interrupt();
}
data_storage_reg_read_t& CMDispatcher::get_reg_data(uint8_t reg_address)
{
    module_general_reg_t& module_general_reg = DataStorageCM::module_reg().module_general_reg;
    switch(reg_address)
    {
        case 0x41:
        {
            static uint8_t interrupt_data[1];
            interrupt_data[0] = module_general_reg.slave_interrupt_reg.value;
            _reg_read.data    =  interrupt_data;
            _reg_read.size    = 1;
            this->clear_interrupt();
        }
        break;
        case 0x50:
        case 0x51:
        {
            module_general_reg.module_general_channel[0].slave_current_sample_value_reg.value = _as.a0_buffer();
            _reg_read.data    =  module_general_reg.module_general_channel[0].slave_current_sample_value_reg.data;
            _reg_read.size    = sizeof(module_general_reg.module_general_channel[0].slave_current_sample_value_reg.data);
        }
        break;
        case 0x52:
        case 0x53:
        {
            module_general_reg.module_general_channel[1].slave_current_sample_value_reg.value = _as.a1_buffer();
            _reg_read.data    =  module_general_reg.module_general_channel[1].slave_current_sample_value_reg.data;
            _reg_read.size    = sizeof(module_general_reg.module_general_channel[1].slave_current_sample_value_reg.data);
        }
        break;
        case 0x54:
        case 0x55:
        {
            module_general_reg.module_general_channel[2].slave_current_sample_value_reg.value = _as.a2_buffer();
            _reg_read.data    =  module_general_reg.module_general_channel[2].slave_current_sample_value_reg.data;
            _reg_read.size    = sizeof(module_general_reg.module_general_channel[2].slave_current_sample_value_reg.data);
        }
        break;
        case 0x56:
        case 0x57:
        {
            module_general_reg.module_general_channel[3].slave_current_sample_value_reg.value = _as.a3_buffer();
            _reg_read.data    =  module_general_reg.module_general_channel[3].slave_current_sample_value_reg.data;
            _reg_read.size    = sizeof(module_general_reg.module_general_channel[3].slave_current_sample_value_reg.data);
            // log::debug("0x43->read:%d:%d(%d)\r\n", _reg_read.data[0], _reg_read.data[1], module_general_reg.module_general_channel[3].slave_current_sample_value_reg.value);

        }
        break;
        default:
        {
            return _ds.get_reg_data(reg_address);
        }
        break;
    }
    
    return  _reg_read;
}
void CMDispatcher::set_sample_enabled(CMChannelName name,bool enable)
{

}
void CMDispatcher::set_threshold_alarm_enabled(CMChannelName name,bool enable)
{
    
}
void CMDispatcher::set_all_channel_sample_enabled(bool a0_enable,bool a1_enable,bool a2_enable,bool a3_enable)
{

}
void CMDispatcher::set_all_channel_threshold_alarm_enabled(bool a0_enable,bool a1_enable,bool a2_enable,bool a3_enable)
{
    
}
int CMDispatcher::apply_median_filter(uint8_t ch_id)
{
    int v=0;
    switch(ch_id)
    {
        case 0:v =_as.a0_buffer() ;break;
        case 1:v =_as.a1_buffer() ;break;
        case 2:v =_as.a2_buffer() ;break;
        case 3:v =_as.a3_buffer() ;break;
        default:break;
    }
    return v;
	// int data[3];
    // for(uint8_t i=0;i<3;i++){
    //     delay(_sample_interval_ms);
    //     data[i] = analogRead(pin);
    // }
    // return  (data[0] > data[1]) ? (data[1] > data[2] ? data[1] : (data[0] > data[2] ? data[2] : data[0])) : (data[0] > data[2] ? data[0] : (data[1] > data[2] ? data[2] : data[1]));
}
bool CMDispatcher::apply_compare(uint8_t ch_id)
{   

    module_general_reg_t& module_general_reg = DataStorageCM::module_reg().module_general_reg;
    //log::debug("apply compare symbol:%d\r\n",module_general_reg.module_general_channel[ch_id].slave_current_sample_threshold_reg.symbol);
    switch(module_general_reg.module_general_channel[ch_id].slave_current_sample_threshold_reg.symbol)
    {
        case 0://<
        {
            if(module_general_reg.module_general_channel[ch_id].slave_current_sample_value_reg.value <
                module_general_reg.module_general_channel[ch_id].slave_current_sample_threshold_reg.value){
                return true;
            }
        }
        break;
        case 1://=
        {
            if(module_general_reg.module_general_channel[ch_id].slave_current_sample_value_reg.value >=
                module_general_reg.module_general_channel[ch_id].slave_current_sample_threshold_reg.value){
                return true;
            }
        }
        break;
        case 2://>
        {   
            if(module_general_reg.module_general_channel[ch_id].slave_current_sample_value_reg.value >
                module_general_reg.module_general_channel[ch_id].slave_current_sample_threshold_reg.value){
                return true;
            }
            //log::debug(">>> %d?%d\r\n",module_general_reg.module_general_channel[ch_id].slave_current_sample_value_reg.value,module_general_reg.module_general_channel[ch_id].slave_current_sample_threshold_reg.value);
        }
        break;
        case 3://<=
        {
            if(module_general_reg.module_general_channel[ch_id].slave_current_sample_value_reg.value <=
                module_general_reg.module_general_channel[ch_id].slave_current_sample_threshold_reg.value){
                return true;
            }
        }
        break;
        case 4://>=
        {
            if(module_general_reg.module_general_channel[ch_id].slave_current_sample_value_reg.value >=
                module_general_reg.module_general_channel[ch_id].slave_current_sample_threshold_reg.value){
                return true;
            }
        }
        break;
        case 5://!=
        {
            if(module_general_reg.module_general_channel[ch_id].slave_current_sample_value_reg.value !=
                module_general_reg.module_general_channel[ch_id].slave_current_sample_threshold_reg.value){
                return true;
            }
        }
        break;
        default:break;
    }
    
    return false;
}
void CMDispatcher::schedule()
{
    module_general_reg_t& module_general_reg = DataStorageCM::module_reg().module_general_reg;

    if(module_general_reg.current_sample_channel_enable_reg.a0==1){
        //读取电流
        module_general_reg.module_general_channel[0].slave_current_sample_value_reg.value = this->apply_median_filter(0);
        //符号判断
        if(module_general_reg.slave_interrupt_reg.a0 == 0 && module_general_reg.current_sample_threshold_alarm_enable_reg.a0==1){
           if(this->apply_compare(0)){
                module_general_reg.slave_interrupt_reg.a0 = 1;
                _interrupt_pin = 1;
                log::debug("alert A0\r\n");
           }
        }
    }
    
    if(module_general_reg.current_sample_channel_enable_reg.a1==1){
        //读取电流
        module_general_reg.module_general_channel[1].slave_current_sample_value_reg.value = this->apply_median_filter(1);
        //符号判断
        if(module_general_reg.slave_interrupt_reg.a1 == 0 &&module_general_reg.current_sample_threshold_alarm_enable_reg.a1==1){
           if(this->apply_compare(1)){
                module_general_reg.slave_interrupt_reg.a1 = 1;
                _interrupt_pin = 1;
                log::debug("alert A1\r\n");
           }
        }
    }

    if(module_general_reg.current_sample_channel_enable_reg.a2==1){
        //读取电流
        module_general_reg.module_general_channel[2].slave_current_sample_value_reg.value = this->apply_median_filter(2);
        //符号判断
        if(module_general_reg.slave_interrupt_reg.a2 == 0 && module_general_reg.current_sample_threshold_alarm_enable_reg.a2==1){
           if(this->apply_compare(2)){
                module_general_reg.slave_interrupt_reg.a2 = 1;
                _interrupt_pin = 1;
                log::debug("alert A2\r\n");
           }
        }
    }
    if(module_general_reg.current_sample_channel_enable_reg.a3==1){
        //读取电流
        module_general_reg.module_general_channel[3].slave_current_sample_value_reg.value = this->apply_median_filter(3);
         //符号判断
        if( (module_general_reg.slave_interrupt_reg.a3 == 0) && (module_general_reg.current_sample_threshold_alarm_enable_reg.a3==1)){
           if(this->apply_compare(3)){
                module_general_reg.slave_interrupt_reg.a3 = 1;
                _interrupt_pin = 1;
                log::debug("alert A3\r\n");
           }
        }
    }
   
} 
void CMDispatcher::update()
{

}
void CMDispatcher::cleanup()
{

}
void CMDispatcher::clear_interrupt()
{
    DataStorageCM::module_reg().module_general_reg.slave_interrupt_reg.value= 0;
    DataStorageCM::module_reg().module_general_reg.current_sample_threshold_alarm_enable_reg.value = 0;
    _interrupt_pin = 0;
}

